package com.mxpio.erp.technology.service.impl;

import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.technology.entity.*;
import com.mxpio.erp.common.technology.entity.ProdTecRoutAudit;
import com.mxpio.erp.common.technology.service.ProdTecRoutAuditService;
import com.mxpio.erp.common.technology.service.ProdTecRoutProcTechDrawingService;
import com.mxpio.erp.common.technology.vo.AuditOpinionVO;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.common.util.BeanReflectionUtils;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.policy.impl.CrudType;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author wupaa
 */
@Service
public class ProdTecRoutAuditServiceImpl extends BaseServiceImpl<ProdTecRoutAudit> implements ProdTecRoutAuditService {

    @Autowired
    private ProdTecRoutProcTechDrawingService routProcTechDrawingService;
    private static Date longLongDate;

    static {
        try{
            longLongDate = DateUtils.parseDate("2099-12-31","yyyy-MM-dd");
        }
        catch (ParseException ignored){

        }
    }
    @Override
    @Transactional(readOnly = true)
    public ProdTecRoutAudit listRoutAudit(String routId) {
        List<ProdTecRoutAudit> auditList = JpaUtil.linq(ProdTecRoutAudit.class).equal("routId",routId).list();
        if(CollectionUtils.isNotEmpty(auditList)){
            ProdTecRoutAudit tecRoutAudit = auditList.get(0);
            List<ProdTecRoutProcAudit> allLines = JpaUtil.linq(ProdTecRoutProcAudit.class).in("routId",tecRoutAudit.getRoutId()).list();
            tecRoutAudit.setLineList(allLines);
            return tecRoutAudit;
        }
        return null;
    }

    @Override
    @Transactional(readOnly = false)
    public ProdTecRoutAudit audit(ProdTecRoutAudit audit, AuditOpinionVO auditOpinionVO) {
        String agree = auditOpinionVO.getAgree();
        String auditOpinion = auditOpinionVO.getAuditOpinion();
        if(CommonEnums.YesNo.YES.getCode().equals(agree)){
            if(Objects.isNull(audit.getBeginTime())){
                throw new IllegalArgumentException("生效时间为空");
            }
            Integer version = 1;
            ProdTecRout crrentRout = getCrrentRout(audit.getProductItemCode());
            List<ProdTecRoutProcAudit> routProcAudits = JpaUtil.linq(ProdTecRoutProcAudit.class).equal("routId",audit.getRoutId()).list();
            //查到上一个版本
            if(crrentRout!=null){
                Date currentBeginTime = crrentRout.getBeginTime();
                if(Objects.isNull(currentBeginTime)){
                    throw new IllegalArgumentException("当前版本BOM生效时间为空");
                }
                if(currentBeginTime.compareTo(audit.getBeginTime())>-1){
                    throw new IllegalArgumentException("新审核BOM生效时间必须晚于上一个版本");
                }
                version = getNextVersion(crrentRout.getVersion());
                audit.setNewVersion(version);
                //更新上一个版本数据
                crrentRout.setPrimaryRout("0");
                crrentRout.setEndTime(audit.getBeginTime());

                //处理子表
                if(CollectionUtils.isNotEmpty(routProcAudits)){
                    for(ProdTecRoutProcAudit lineAudit:routProcAudits){//先处理更新和删除
                        if(CrudType.UPDATE.toString().equals(lineAudit.getTmpCrudType())){
                            /*invaildCurrentProdTecRoutProc(lineAudit.getRoutProcId(),audit.getBeginTime());
                            saveNewBomInfoLine(lineAudit,audit);*/
                            //合并方法，处理工序参数
                            invaildCurrentProdTecRoutProcAndSaveNew(lineAudit,audit);
                        }
                        else if(CrudType.DELETE.toString().equals(lineAudit.getTmpCrudType())){
                            invaildCurrentProdTecRoutProc(lineAudit.getRoutProcId(),audit.getBeginTime());
                        }
                    }
                    for(ProdTecRoutProcAudit lineAudit:routProcAudits){//最后处理新增的情况 防止invaildCurrentBomInfoLine逻辑误判
                        if(CrudType.SAVE.toString().equals(lineAudit.getTmpCrudType())){
                            saveNewRoutProc(lineAudit,audit);
                        }
                    }
                }

            }
            else{
                //没有上一个版本，直接新增子表
                if(CollectionUtils.isNotEmpty(routProcAudits)){
                    for(ProdTecRoutProcAudit lineAudit:routProcAudits){
                        if(!CrudType.SAVE.toString().equals(lineAudit.getTmpCrudType())){
                            continue;
                        }
                        saveNewRoutProc(lineAudit,audit);
                    }
                }
            }

            //插入新BOM表
            ProdTecRout newTecRout = new ProdTecRout();
            try{
                BeanReflectionUtils.copyProperties(newTecRout,audit);
            }
            catch (Exception e){
                throw new MBootException("生成新BOM失败");
            }
            newTecRout.setRoutId(null);
            newTecRout.setVersion(version);
            newTecRout.setPrimaryRout("1");
            newTecRout.setEndTime(longLongDate);
            newTecRout.setUseType(OrderStatusEnums.BomStatus.USING.getStatusCode());
            JpaUtil.save(newTecRout);

            //更新原BOM表
            if(crrentRout!=null){
                JpaUtil.update(crrentRout);
            }
            //变更审核状态
            audit.setUseType(OrderStatusEnums.BomStatus.USING.getStatusCode());
        }else{
            //变更审核状态
            audit.setUseType(OrderStatusEnums.BomStatus.VOIDED.getStatusCode());
        }
        audit.setAuditOpinion(auditOpinion);
        audit.setAgree(agree);
        JpaUtil.update(audit);

        //删除草稿
        deleteTmp(audit.getProductItemCode());

        return audit;
    }

    private String getNextVersion(String version){
        String versionNum = StringUtils.substring(version,1,StringUtils.indexOf(version,"."));
        return "V"+(Integer.parseInt(versionNum)+1)+".0";
    }

    private Integer getNextVersion(Integer version){
        version++;
        return version;
    }
    private ProdTecRout getCrrentRout(String productItemCode){
        List<ProdTecRout> currentRoutList = JpaUtil.linq(ProdTecRout.class).equal("productItemCode",productItemCode).equal("primaryRout","1").list();
        if(CollectionUtils.isNotEmpty(currentRoutList)){
            return currentRoutList.get(0);
        }
        return null;
    }

    private void invaildCurrentProdTecRoutProc(String  routProcId, Date endDate){
        ProdTecRoutProc one = JpaUtil.getOne(ProdTecRoutProc.class, routProcId);
        if(one==null){
            throw new MBootException("找不到上一个版本");
        }
        one.setEndTime(endDate);
        JpaUtil.update(one);
    }

    private void saveNewRoutProc(ProdTecRoutProcAudit line, ProdTecRoutAudit audit){
        ProdTecRoutProc routProc = new ProdTecRoutProc();
        try{
            BeanReflectionUtils.copyProperties(routProc,line);
        }
        catch (Exception e){
            throw new MBootException("生成新BOM失败");
        }
        //因为是不同版本的bom公用一套bomLine，所bomId用parentCode关联
        routProc.setRoutId(audit.getProductItemCode());
        routProc.setId(null);
        routProc.setBeginTime(audit.getBeginTime());
        routProc.setEndTime(longLongDate);
        JpaUtil.save(routProc);
    }

    private void invaildCurrentProdTecRoutProcAndSaveNew(ProdTecRoutProcAudit line, ProdTecRoutAudit audit){
        //更新原工序结束日期
        ProdTecRoutProc one = JpaUtil.getOne(ProdTecRoutProc.class, line.getRoutProcId());
        if(one==null){
            throw new MBootException("找不到上一个版本");
        }
        one.setEndTime(audit.getBeginTime());
        JpaUtil.update(one);
        //新增
        ProdTecRoutProc routProc = new ProdTecRoutProc();
        try{
            BeanReflectionUtils.copyProperties(routProc,line);
        }
        catch (Exception e){
            throw new MBootException("生成新BOM失败");
        }
        //因为是不同版本的bom公用一套bomLine，所bomId用parentCode关联
        routProc.setRoutId(audit.getProductItemCode());
        routProc.setId(null);
        routProc.setBeginTime(audit.getBeginTime());
        routProc.setEndTime(longLongDate);
        JpaUtil.save(routProc);
        //拷贝原工序上的参数信息
        List<ProdTecRoutProcDoc> procDocs = JpaUtil.linq(ProdTecRoutProcDoc.class).equal("routProcId", one.getId()).list();
        if (procDocs.size()>0){
            for (ProdTecRoutProcDoc device:procDocs){
                ProdTecRoutProcDoc add = new ProdTecRoutProcDoc();
                BeanReflectionUtils.copyProperties(add,device);
                add.setRoutProcId(routProc.getId());
                add.setId(null);
                JpaUtil.save(add);//保存
            }
        }
        //拷贝原工序上的工装夹具
        List<ProdTecRoutProcFixture> fixtures = JpaUtil.linq(ProdTecRoutProcFixture.class).equal("routProcId", one.getId()).list();
        if (fixtures.size()>0){
            for (ProdTecRoutProcFixture fixture:fixtures){
                ProdTecRoutProcFixture add = new ProdTecRoutProcFixture();
                BeanReflectionUtils.copyProperties(add,fixture);
                add.setRoutProcId(routProc.getId());
                add.setId(null);
                JpaUtil.save(add);//保存
            }
        }
        //拷贝原工序上的工艺图纸信息（最后一个版次、且生效）
        Criteria criteria = Criteria.create();
        criteria.addCriterion("routProcId", Operator.EQ, line.getRoutProcId());
        criteria.addCriterion("version", Operator.EQ,audit.getVersion());//版本
        criteria.addCriterion("primary",Operator.EQ,CommonEnums.YesNo.YES.getCode());//生效
        List<ProdTecRoutProcTechDrawing> prodTecRoutProcTechDrawings = routProcTechDrawingService.list(ProdTecRoutProcTechDrawing.class, criteria);
        if (!prodTecRoutProcTechDrawings.isEmpty()){
            for (int i = 0; i < prodTecRoutProcTechDrawings.size(); i++) {
                ProdTecRoutProcTechDrawing lastVersionEdition = prodTecRoutProcTechDrawings.get(i);
                ProdTecRoutProcTechDrawing copyEdition = new ProdTecRoutProcTechDrawing();
                //从上一版本最新的版次拷贝
                copyEdition.setFileNo(lastVersionEdition.getFileNo());
                copyEdition.setFileName(lastVersionEdition.getFileName());
                copyEdition.setLength(lastVersionEdition.getLength());
                copyEdition.setExtension(lastVersionEdition.getExtension());
                copyEdition.setRemarks(lastVersionEdition.getRemarks());

                //赋值
                copyEdition.setRoutProcId(routProc.getId());
                copyEdition.setFamily(UUID.randomUUID().toString().replace("-",""));
                copyEdition.setVersion(audit.getNewVersion());
                JpaUtil.save(copyEdition);
            }
        }
    }

    private void deleteTmp(String productItemCode){
        //删草稿
        List<ProdTecRoutTmp> bomInfoTmpList = JpaUtil.linq(ProdTecRoutTmp.class).equal("productItemCode",productItemCode).list();
        if(CollectionUtils.isNotEmpty(bomInfoTmpList)){
            for(ProdTecRoutTmp bomInfoTmp : bomInfoTmpList){
                JpaUtil.lind(ProdTecRoutProcTmp.class).equal("routId",bomInfoTmp.getRoutId()).delete();
                JpaUtil.lind(ProdTecRoutTmp.class).equal("routId",bomInfoTmp.getRoutId()).delete();
            }
        }
    }
}
